<template>
	<view>
		<view class="content">
			<view v-if="isSet">
				<view class="title">设置手势密码</view>
				<view class="msg">{{msg}}</view>
			</view>
			<view v-if="!isSet" class="logo">
				<image src="/static/img/login/avatar.png" class="logo-img"></image>
				<view class="username">{{usernameSave}}</view>
				<view v-if="msg!=''" class="tip">{{msg}}</view>
			</view>
			<canvas canvas-id="pwd" class="grid" :style="{width:side.width+'px', height:side.height+'px'}" @touchstart="touchstart"
			 @touchmove="touchmove" @touchend="touchend"></canvas>
			<view  v-if="!isSet" class="more">
			 <text @click="showActions">更多</text>
			</view>
		</view>
	</view>
</template>

<script>
	import mixins from '@/mixins/index';
	import {judgeExpireTimestamp} from '@/utils/index';
	import {refreshForlogin} from '@/utils/page'
	import { mapState } from 'vuex';
	import {Decrypt} from '@/utils/secret.js'
	export default {
		mixins:[mixins],
		data() {
			return {
				baseColor: "#bfc8e1",
				lightColor: "#5ea1f8",
				wrongColor: "#e26262",
				wrongLineColor: "#f7cece",
				lineWidth: uni.upx2px(2),
				strokeWidth: uni.upx2px(2),
				status: 0,
				purpose: "unlock",
				maxCount: 5,

				radius: 0, //大圈半径
				pointData: [], //点对象集合
				type: 3, //每行点数，3就是9宫格
				touchFlag: false, //是否开始绘制手势
				touchedPoint: [], //存储经过的点对象
				untouchedPoint: [],
				endX: 0,
				endY: 0,
				pwd: {
					first: undefined,
					second: undefined
				},
				realPwd: undefined,
				count: 0,
				time: 30
			}
		},
		computed: {
			...mapState({
				systemInfo:state=>state.settings.systemInfo
			}),
			side(){
				const specs = this.isPad?uni.upx2px(500):uni.upx2px(700)
				return {
					width:specs,
					height:specs,
				}
			},
			isPad(){
				console.log('systemInfo:',this.systemInfo)
				return this.systemInfo.windowHeight / this.systemInfo.windowWidth < 1.7
			},
			isSet() {
				return 'set' == this.purpose;
			},
			isLock() {
				return this.count >= this.maxCount
			},
			msg() {
				return {
					0:"绘制解锁图案,至少连接四个点",
					1:"至少连接四个点,请重试",
					3:"请再次绘制解锁图案",
					4:"两次绘制图案不一样，请重新设置",
					6:"您的新解锁图案设置成功",
					7:"",
					8:"密码错误",
					10:"解锁成功",
					11:`错误次数太多，请${this.time}s后再试`,
				}[this.status]
				// switch (this.status) {
				// 	case 0:
				// 		return "绘制解锁图案,至少连接四个点"
				// 	case 1:
				// 		return "至少连接四个点,请重试"
				// 	case 3:
				// 		return "请再次绘制解锁图案"
				// 	case 4:
				// 		return "两次绘制图案不一样，请重新设置"
				// 	case 6:
				// 		return "您的新解锁图案："
				// 	case 7:
				// 		return ""
				// 	case 8:
				// 		return "密码错误"
				// 	case 10:
				// 		return "解锁成功"
				// 	case 11:
				// 		return "错误次数太多，请" + this.time + "s后再试"
				// 	default:
				// 		break;
				// }
			},
			resetDisable() {
				return this.pwd.first == undefined
			},
			finishDisable() {
				return this.status != 6
			},
			minWidthHeight(){
				return this.side.width>this.side.height?this.side.width:this.side.height
			},
		},

		onLoad({purpose='unlock'}) {
			uni.hideKeyboard();
			this.purpose = purpose;
			if ("unlock" == this.purpose) {
				this.status = 7;
				this.realPwd = this.userDataForLogin.gesture;
				console.log('realPwd:',this.realPwd)
			}else{
				uni.setNavigationBarTitle({
					title: '手势修改'
				});
			}
		},
		 onReady(){
			 this.initData();
			this.initDraw();
        },
		methods: {
			showActions(){
				uni.showActionSheet({
                  itemList: ['切换账号', '切换密码登录'],
                  success: function (res) {
                      uni.redirectTo({
						  url:'/pages/system/login/index'
					  })
					}
				});
			},
			//倒计时显示
			countDown(color, time) {
				this.drawTouchedPoint(this.endX, this.endY, color);
				let self = this;
				setTimeout(function() {
					self.resetCanvas();
				}, time)
			},
			resetData() {
				this.touchedPoint = [];
				this.untouchedPoint = [];
				for (let item of this.pointData) {
					item.isTouched = false;
					this.untouchedPoint.push(item);
				}
			},
			resetCanvas() {
				this.resetData();
				this.initDraw();
			},
			initData() {
				this.calculateRadius();
				this.initPointData();
			},
			//根据canvas宽高计算每个圈的半径
			calculateRadius() {
				this.radius = this.minWidthHeight / (4 * this.type + 2);
			},
			//初始化9宫格的位置对象
			initPointData() {
				const {
					type,
					radius
				} = this;
				let count = 0;
				for (let i = 0; i < type; i++) {
					for (let j = 0; j < type; j++) {
						count++;
						let point = {
							x: j * 4 * radius + 3 * radius,
							y: i * 4 * radius + 3 * radius,
							index: count,
							isTouched: false
						}
						this.pointData.push(point);
						this.untouchedPoint.push(point);
					}
				}
			},
			initDraw() {
				let ctx = uni.createCanvasContext("pwd");
				this.drawPoint(ctx, this.baseColor);
				ctx.draw();
			},
			//画9宫格
			drawPoint(ctx, lightColor) {
				const {
					lineWidth,
					baseColor,
					radius,
					strokeWidth
				} = this;
				let centerRadius = radius / 2;
				let ringRadius = radius * 0.75;
				for (let item of this.pointData) {
					if (item.isTouched) {
						this.drawRing(ctx, lightColor, centerRadius, ringRadius, item);
						this.drawCenter(ctx, lightColor, strokeWidth, centerRadius, item)
						this.drawCircle(ctx, lightColor, strokeWidth, radius, item);
					} else {
						this.drawCenter(ctx, baseColor, strokeWidth, centerRadius, item)
					}
				}
			},
			//画空心圆圈
			drawCircle(ctx, color, lineWidth, radius, item) {
				ctx.setStrokeStyle(color);
				ctx.setLineWidth(lineWidth);
				ctx.setGlobalAlpha(1);
				ctx.beginPath();
				ctx.arc(item.x, item.y, radius, 0, 2 * Math.PI);
				ctx.stroke();
			},
			//画半透明环
			drawRing(ctx, color, ringWidth, radius, item) {
				ctx.setStrokeStyle(color);
				ctx.setLineWidth(ringWidth);
				ctx.setGlobalAlpha(0.3);
				ctx.beginPath();
				ctx.arc(item.x, item.y, radius, 0, 2 * Math.PI);
				ctx.stroke();
			},
			//画实心
			drawCenter(ctx, color, lineWidth, radius, item) {
				ctx.setFillStyle(color);
				ctx.setLineWidth(lineWidth);
				ctx.setGlobalAlpha(1);
				ctx.beginPath();
				ctx.arc(item.x, item.y, radius, 0, 2 * Math.PI);
				ctx.fill();
			},
			//画连线
			drawLinePath(ctx, color, currentX, currentY) {
				const {
					touchedPoint,
					lineWidth
				} = this;
				if (touchedPoint.length == 0) {
					return;
				}
				ctx.beginPath();
				for (let i = 0; i < touchedPoint.length; i++) {
					let item = touchedPoint[i];
					ctx.setStrokeStyle(color);
					ctx.setLineWidth(lineWidth);
					if (i == 0) {
						ctx.moveTo(item.x, item.y);
					} else {
						ctx.lineTo(item.x, item.y);
					}
				}
				ctx.lineTo(currentX, currentY);
				ctx.stroke();
			},
			//绘制触摸后变成实心的点和线条路径
			drawTouchedPoint(x, y, lightColor) {
				let ctx = uni.createCanvasContext("pwd");
				const {
					side,
					baseColor
				} = this;
				ctx.clearRect(0, 0, side.width, side.height);
				this.drawPoint(ctx, lightColor, this.pointData);
				this.drawLinePath(ctx, lightColor, x, y);
				ctx.draw();
			},
			//触摸事件
			touchstart(e) {
				if (this.isLock) {
					return false;
				}
				this.resetData();
				const {
					radius
				} = this;
				const x = e.mp.changedTouches[0].x;
				const y = e.mp.changedTouches[0].y;
				for (let i = 0; i < this.pointData.length; i++) {
					let item = this.pointData[i];
					let xDistance = Math.abs(x - item.x);
					let yDistance = Math.abs(y - item.y);
					if (xDistance <= radius && yDistance <= radius) {
						this.touchFlag = true;
						item.isTouched = true;
						this.touchedPoint.push(item);
						this.untouchedPoint.splice(i, 1);
						break;
					}
				}
				this.drawTouchedPoint(x, y, this.lightColor);
			},
			touchmove(e) {
				if (!this.touchFlag || this.isLock) {
					return false;
				}
				const {
					radius
				} = this;
				const x = e.mp.changedTouches[0].x;
				const y = e.mp.changedTouches[0].y;
				for (let i = 0; i < this.untouchedPoint.length; i++) {
					let item = this.untouchedPoint[i];
					let xDistance = Math.abs(x - item.x);
					let yDistance = Math.abs(y - item.y);
					if (xDistance <= radius && yDistance <= radius) {
						item.isTouched = true;
						this.touchedPoint.push(item);
						this.untouchedPoint.splice(i, 1);
					}
				}
				this.drawTouchedPoint(x, y, this.lightColor);
			},
			touchend(e) {
				if (!this.touchFlag || this.isLock) {
					return false;
				}
				this.endX = e.mp.changedTouches[0].x;
				this.endY = e.mp.changedTouches[0].y;
				this.touchFlag = false;
				this.end(this.getPwd());
			},
			getPwd() {
				let pwd = "";
				for (let item of this.touchedPoint) {
					pwd += item.index;
				}
				return pwd;
			},
			end(pwd) {
				console.log(pwd);
				console.log(this.status);
				switch (this.status) {
					case 0:
					case 1:
					case 4:
						this.handleFirst(pwd, 1)
						break;
					case 3:
						this.handleSecond(pwd, 4);
						break;
					case 7:
					case 8:
						this.handleUnlock(pwd, 8)
						break;
					default:
						break;
				}
				this.watchStatus();
			},
			watchStatus() {
				let newStatus = this.status;
				if (newStatus == 1 ||
					newStatus == 4 ||
					newStatus == 8 || newStatus == 11) {
					this.countDown(this.wrongColor, 1000);
				} else if (newStatus == 3) {
					this.resetCanvas();
				}
			},

			handleFirst(pwd, status) {
				if (pwd.length < 4) {
					this.status = status
				} else {
					this.status = 3;
					this.pwd.first = pwd;
				}
			},
			handleSecond(pwd, status) {
				if (this.pwd.first == pwd) {
					this.status = 6;
					this.pwd.second = pwd
					this.setSuccess(pwd);
				} else {
					this.pwd.first = "";
					this.status = status;
				}
			},
			handleUnlock(pwd, status) {
				console.log('handleUnlock')
				const {devicNum} = this.userDataForLogin
				const username  = Decrypt(this.userDataForLogin.username)
				const params = {
                            username,
							devicNum,
							gesture:pwd,
							option:'gesture'
                        }
				let callback = (validUser)=>{
                    if (validUser) {
                        this.setUserDataForLogin(params)
						refreshForlogin(this);
						this.status = 10;
						this.unlockSuccess();
                    } else {
                        uni.showToast({
                            icon: 'none',
                            title: '手势密码不正确',
						});
						this.status = status
						this.checkCount();
                    }
                };
                this.login({
                    ...params,
                   // gps:this.gps,
                    callback: callback
                });
			},
			//检查是否超过次数
			checkCount() {
				this.count++;
				if (this.isLock) {
					//倒计时30s
					this.status = 11;
					let countDown;
					let self = this;
					countDown = setInterval(function() {
						self.time--;
						if (self.time <= 0) {
							clearInterval(countDown);
							self.status = 7;
							self.count = 0;
							self.time = 30;
						}
					}, 1000)
				}
			},
			//设置成功回调
			setSuccess(pwd) {
				//uni.setStorageSync("pwd", this.pwd.first);
				const {devicNum} = this.userDataForLogin
				const username  = Decrypt(this.userDataForLogin.username)
				this.setUserDataForLogin({
                            username,
							devicNum,
							gesture:this.pwd.first,
							callback:()=>{
								setTimeout(()=>{
									uni.showToast({
										title: '手势修改成功',
										duration: 1500,
										icon:'none'
									});
									uni.navigateBack()
								},500)
							}
                        })
			},
			//解锁成功回调
			unlockSuccess() {
				console.log("unlock success");
			},
			//切换到密码登录
			trigger() {
				if(this.isLastPage()){
					uni.navigateTo({
						url: "/pages/system/login/index"
					})
				}
				uni.navigateBack();
			},
			reset() {
				this.status = 0;
				this.pwd.first = undefined;
				this.pwd.second = undefined;
				this.resetCanvas();
			},
		}
	}
</script>

<style lang="scss" scoped>
	.content {
		margin-top: 10upx;
		// max-height: 100%;
		// position: fixed;
		// top: 0;
		// bottom: 0;
		// left: 0;
		// right: 0;
	}

	.title {
		font-size: 36upx;
		color: #333333;
		text-align: center;
	}
	.username{
		font-size: 36upx;
		color: #333333;
		text-align: center;
		margin: 10upx 0 0upx;
		&-wrong {
			color: #e26262;
		}
	}

	.msg {
		font-size: 24upx;
		color: #333333;
		text-align: center;
		margin: 40upx 0 80upx;

		&-wrong {
			color: #e26262;
		}
	}
	.tip{
		font-size: 24upx;
		color: #e26262;
		text-align: center;
	}

	.more {
		font-size: 28upx;
		color: #333333;
		text-align: center;

		&-wrong {
			color: #e26262;
		}
	}

	.logo {
		text-align: center;
		padding: 120upx 0 0upx;

		&-img {
			width: 160upx;
			height: 160upx;
		}
	}

	.grid {
		margin: 0 auto;
	}

	.trigger {
		text-align: center;
		font-size: 28upx;
		color: #333333;
	}
</style>
